#include <stdio.h>
#include <stdlib.h>
#include "stack_queue.h"

int sqq_init(sq_queue *queue){
    queue->front = queue->rear = 0;
    return 0;
}

int sqq_in(sq_queue *queue, int data){
    if((queue->rear + 1) % MAX_SIZE == queue->front){
        printf("queue full\n");
        return -1;
    }

    queue->data[queue->rear] = data;
    queue->rear =  (queue->rear + 1) % MAX_SIZE;

    return 0;
}

int sqq_out(sq_queue *queue, int *data){
    if(queue->rear == queue->front){
        printf("queue is empty\n");
        return -1;
    }

    *data = queue->data[queue->front];
    queue->front = (queue->front + 1) % MAX_SIZE;

    return 0;
}

int sqq_length(sq_queue *queue){
    return (queue->rear - queue->front +MAX_SIZE) % MAX_SIZE;
}

int lq_init(lqlist *list){
    *list = (lqlist)malloc(sizeof(lqueue));
    if (*list == NULL) {
        perror("malloc");
        return -1;
    }

    lqnode *new = (lqnode *)malloc(sizeof(lqnode));
    if(new == NULL){
        perror("malloc");
        free(*list);
        return -1;
    }

    new->next = NULL;
    (*list)->front = (*list)->rear = new;

    return 0;
}

int lq_in(lqlist *list, int data){
    lqnode *new =(lqnode *)malloc(sizeof(lqnode));
    if(new == NULL){
        perror("malloc");
        return -1;
    }

    new->data = data;
    new->next = NULL;
    (*list)->rear->next = new;
    (*list)->rear = new;

    return 0;
}

int lq_out(lqlist *list, int *data){
    if((*list)->front == (*list)->rear){
        printf("queue is empty\n");
        return -1;
    }

    lqnode *target = (*list)->front->next;
    *data = target->data;
    (*list)->front->next = target->next;

    if(target == (*list)->rear){
        (*list)->rear = (*list)->front;
    }
    free(target);

    return 0;
}

int lq_destroy(lqlist *list){
    while((*list)->front != NULL){
        lqnode *tmp = (*list)->front;
        (*list)->front = tmp->next;
        free(tmp);
    }

    free(*list);
    return 0;
}

int lq_length(lqlist *list){
    if((*list)->front == (*list)->rear)
        return 0;
    
    int i = 0;
    lqnode *tmp = (*list)->front->next;
    while (tmp != NULL){
        i++;
        tmp = tmp->next;
    }
    
    return i;
}